//
//  UIControl+XYAdd.m
//  PeiJue
//
//  Created by lxy on 2017/9/28.
//  Copyright © 2017年 lixiya. All rights reserved.
//

#import "UIControl+XYAdd.h"
#import <objc/runtime.h>

static const void * XYUIControlBlockTagretKey = "XYUIControlBlockTagretKey";

@interface _XYUIControlBlockTagret : NSObject

@property(nonatomic ,copy) void(^block)(id sender);
@property(nonatomic ,assign) UIControlEvents events;

-(instancetype)initWithBlock:(void(^)(id sender))block events:(UIControlEvents)events;
-(void)invoke:(id)sender;

@end

@implementation _XYUIControlBlockTagret

-(instancetype)initWithBlock:(void (^)(id))block events:(UIControlEvents)events{
    if (self = [super init]) {
        _block = [block copy];
        _events = events;
    }
    return self;
}

-(void)invoke:(id)sender{
    
    if (_block) {
        _block(sender);
    }
}

@end

@implementation UIControl (XYAdd)

-(void)xy_removeAllTargets{
    
    [[self allTargets] enumerateObjectsUsingBlock:^(id  _Nonnull obj, BOOL * _Nonnull stop) {
        [self removeTarget:obj action:NULL forControlEvents:UIControlEventAllEvents];
    }];
    
    [[self xy_allUIControlBlockTargets] removeAllObjects];
    
}


-(void)xy_setTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents{
    
    if (!target || !action || !controlEvents) return;
    // 获取该控件绑定的所有target/action
    NSSet *targets = [self allTargets];
    for (id currentTarget in targets) {
        //获取指定目标对象上指定事件的行为方法名称数组
        NSArray *actions = [self actionsForTarget:currentTarget forControlEvent:controlEvents];
        for (NSString *currentAction in actions) {
            [self removeTarget:currentTarget action:NSSelectorFromString(currentAction)
              forControlEvents:controlEvents];
        }
    }
    [self addTarget:target action:action forControlEvents:controlEvents];
    
}

-(void)xy_addBlockForControlEvents:(UIControlEvents)controlEvents block:(void (^)(id _Nonnull))block{
    
    if (!controlEvents) return;
    _XYUIControlBlockTagret * target = [[_XYUIControlBlockTagret alloc] initWithBlock:block events:controlEvents];
    
    [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents];
    
    NSMutableArray *targets =  [self xy_allUIControlBlockTargets];
    [targets addObject:target];
    
}


-(void)xy_setBlockForControlEvents:(UIControlEvents)controlEvents block:(void (^)(id _Nonnull))block{
    
    [self xy_removeAllBlocksForControlEvents:controlEvents];
    [self xy_addBlockForControlEvents:controlEvents block:block];
    
}

-(void)xy_removeAllBlocksForControlEvents:(UIControlEvents)controlEvents{
    
    NSMutableArray *targets = [self xy_allUIControlBlockTargets];
    NSMutableArray *removes = [NSMutableArray array];
    for (_XYUIControlBlockTagret *target in targets) {
        if (target.events & controlEvents) {
            UIControlEvents newEvent = target.events & (~controlEvents);
            if (newEvent) {
                [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events];
                target.events = newEvent;
                [self addTarget:target action:@selector(invoke:) forControlEvents:target.events];
            } else {
                [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events];
                [removes addObject:target];
            }
        }
    }
    [targets removeObjectsInArray:removes];
    
}

- (NSMutableArray *)xy_allUIControlBlockTargets {
    NSMutableArray *targets = objc_getAssociatedObject(self, XYUIControlBlockTagretKey);
    if (!targets) {
        targets = [NSMutableArray array];
        objc_setAssociatedObject(self, XYUIControlBlockTagretKey, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return targets;
}


@end

